import React, { useState, useEffect, useRef } from 'react';
import { invoke } from '@tauri-apps/api/core';
import { Plus, Send, Trash2, MessageSquare, Loader2, Edit2, Check, X, Mic, MicOff, Volume2, VolumeX } from 'lucide-react';
import { motion } from 'framer-motion';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { useAuth } from '@/contexts/AuthContext';

interface AiModel {
  id: number;
  name: string;
  model_id: string;
  model_type: string;
}

interface Conversation {
  id: number;
  title: string;
  model_id: number;
  created_at: string;
  updated_at: string;
}

interface Message {
  id: number;
  conversation_id: number;
  role: 'user' | 'assistant';
  content: string;
  created_at: string;
}

export default function AIChat() {
  const { isAuthenticated } = useAuth();
  const [models, setModels] = useState<AiModel[]>([]);
  const [conversations, setConversations] = useState<Conversation[]>([]);
  const [currentConversation, setCurrentConversation] = useState<Conversation | null>(null);
  const [messages, setMessages] = useState<Message[]>([]);
  const [inputMessage, setInputMessage] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [isSending, setIsSending] = useState(false);
  const [editingTitle, setEditingTitle] = useState<number | null>(null);
  const [editTitle, setEditTitle] = useState('');
  const messagesEndRef = useRef<HTMLDivElement>(null);
  
  // Voice input state
  const [isListening, setIsListening] = useState(false);
  const [voiceSupported, setVoiceSupported] = useState(false);
  const recognitionRef = useRef<any>(null);
  
  // Text-to-speech state
  const [speakingMessageId, setSpeakingMessageId] = useState<number | null>(null);
  const [ttsSupported, setTtsSupported] = useState(false);
  const [autoSpeak, setAutoSpeak] = useState(() => {
    // Load auto-speak preference from localStorage
    const saved = localStorage.getItem('ai_chat_auto_speak');
    return saved === 'true';
  });
  const speechSynthesisRef = useRef<SpeechSynthesis | null>(null);
  const lastMessageIdRef = useRef<number | null>(null);

  useEffect(() => {
    if (isAuthenticated) {
      loadModels();
      loadConversations();
    }
  }, [isAuthenticated]);

  useEffect(() => {
    if (currentConversation) {
      loadMessages(currentConversation.id);
    }
  }, [currentConversation]);

  useEffect(() => {
    scrollToBottom();
  }, [messages]);

  // Auto-speak when new AI message arrives
  useEffect(() => {
    if (!autoSpeak || !ttsSupported || messages.length === 0) return;

    // Get the last message
    const lastMessage = messages[messages.length - 1];
    
    // Only auto-speak assistant messages and avoid re-speaking the same message
    if (
      lastMessage.role === 'assistant' && 
      lastMessage.id && 
      lastMessage.id !== lastMessageIdRef.current
    ) {
      lastMessageIdRef.current = lastMessage.id;
      
      // Wait a bit to ensure the message is rendered
      setTimeout(() => {
        speakMessage(lastMessage.id!, lastMessage.content);
      }, 300);
    }
  }, [messages, autoSpeak, ttsSupported]);

  // Save auto-speak preference to localStorage
  useEffect(() => {
    localStorage.setItem('ai_chat_auto_speak', String(autoSpeak));
  }, [autoSpeak]);

  const scrollToBottom = () => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  };

  // Initialize text-to-speech
  useEffect(() => {
    if ('speechSynthesis' in window) {
      setTtsSupported(true);
      speechSynthesisRef.current = window.speechSynthesis;
    }
    
    return () => {
      // Clean up any ongoing speech
      if (speechSynthesisRef.current) {
        speechSynthesisRef.current.cancel();
      }
    };
  }, []);

  // Initialize speech recognition
  useEffect(() => {
    // Check if browser supports speech recognition
    const SpeechRecognition = (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition;
    
    if (SpeechRecognition) {
      setVoiceSupported(true);
      
      const recognition = new SpeechRecognition();
      recognition.continuous = true;
      recognition.interimResults = true;
      recognition.lang = 'zh-CN'; // 设置为中文，也可以改为 'en-US' 英文
      
      recognition.onresult = (event: any) => {
        let interimTranscript = '';
        let finalTranscript = '';
        
        for (let i = event.resultIndex; i < event.results.length; i++) {
          const transcript = event.results[i][0].transcript;
          if (event.results[i].isFinal) {
            finalTranscript += transcript + ' ';
          } else {
            interimTranscript += transcript;
          }
        }
        
        // Update input with final transcript
        if (finalTranscript) {
          setInputMessage(prev => prev + finalTranscript);
        }
      };
      
      recognition.onerror = (event: any) => {
        console.error('Speech recognition error:', event.error);
        setIsListening(false);
        
        // Show user-friendly error messages
        if (event.error === 'not-allowed' || event.error === 'permission-denied') {
          alert('请允许浏览器访问麦克风权限');
        } else if (event.error === 'no-speech') {
          alert('未检测到语音，请重试');
        } else {
          alert('语音识别出错: ' + event.error);
        }
      };
      
      recognition.onend = () => {
        setIsListening(false);
      };
      
      recognitionRef.current = recognition;
    }
    
    return () => {
      if (recognitionRef.current) {
        recognitionRef.current.stop();
      }
    };
  }, []);

  const toggleVoiceInput = () => {
    if (!voiceSupported) {
      alert('您的浏览器不支持语音识别功能');
      return;
    }
    
    if (isListening) {
      // Stop listening
      recognitionRef.current?.stop();
      setIsListening(false);
    } else {
      // Start listening
      try {
        recognitionRef.current?.start();
        setIsListening(true);
      } catch (error) {
        console.error('Failed to start speech recognition:', error);
        alert('启动语音识别失败，请重试');
      }
    }
  };

  const speakMessage = (messageId: number, text: string) => {
    if (!ttsSupported || !speechSynthesisRef.current) {
      alert('您的浏览器不支持语音朗读功能');
      return;
    }

    // If already speaking this message, stop it
    if (speakingMessageId === messageId) {
      speechSynthesisRef.current.cancel();
      setSpeakingMessageId(null);
      return;
    }

    // Stop any ongoing speech
    speechSynthesisRef.current.cancel();

    // Wait a bit for cancel to complete
    setTimeout(() => {
      if (!speechSynthesisRef.current) return;

      // Create utterance
      const utterance = new SpeechSynthesisUtterance(text);
      utterance.lang = 'zh-CN'; // 设置为中文，也可以改为 'en-US' 英文
      utterance.rate = 1.0; // 语速
      utterance.pitch = 1.0; // 音调
      utterance.volume = 1.0; // 音量

      utterance.onstart = () => {
        setSpeakingMessageId(messageId);
      };

      utterance.onend = () => {
        setSpeakingMessageId(null);
      };

      utterance.onerror = (event) => {
        console.error('Speech synthesis error:', event);
        setSpeakingMessageId(null);
        
        // Only show error alert for non-canceled errors
        // 'canceled' and 'interrupted' are normal when user stops speech
        if (event.error !== 'canceled' && event.error !== 'interrupted') {
          alert('朗读出错: ' + event.error);
        }
      };

      speechSynthesisRef.current.speak(utterance);
    }, 100);
  };

  const loadModels = async () => {
    try {
      const result = await invoke<AiModel[]>('get_ai_models');
      setModels(result.map(m => ({
        id: m.id,
        name: m.name,
        model_id: m.model_id,
        model_type: m.model_type,
      })));
    } catch (error) {
      console.error('Failed to load models:', error);
    }
  };

  const loadConversations = async () => {
    try {
      const result = await invoke<Conversation[]>('get_conversations');
      setConversations(result);
    } catch (error) {
      console.error('Failed to load conversations:', error);
    }
  };

  const loadMessages = async (conversationId: number) => {
    try {
      setIsLoading(true);
      const result = await invoke<Message[]>('get_messages', {
        conversationId,
      });
      setMessages(result);
    } catch (error) {
      console.error('Failed to load messages:', error);
    } finally {
      setIsLoading(false);
    }
  };

  const createNewConversation = async (modelId: number) => {
    try {
      const title = `新对话`;  // 简化默认标题，将由AI自动生成
      const conversationId = await invoke<number>('create_conversation', {
        title,
        modelId,
      });
      await loadConversations();
      const newConv = conversations.find(c => c.id === conversationId) || {
        id: conversationId,
        title,
        model_id: modelId,
        created_at: new Date().toISOString(),
        updated_at: new Date().toISOString(),
      };
      setCurrentConversation(newConv);
      setMessages([]);
    } catch (error) {
      console.error('Failed to create conversation:', error);
      alert('创建对话失败: ' + error);
    }
  };

  const deleteConversation = async (id: number, event?: React.MouseEvent) => {
    // 阻止事件冒泡，防止触发对话切换
    if (event) {
      event.preventDefault();
      event.stopPropagation();
    }

    // 显示确认对话框
    const confirmed = window.confirm('确定要删除这个对话吗？\n\n此操作将永久删除该对话及其所有消息，且无法恢复。');
    
    if (!confirmed) {
      return; // 用户点击取消，不执行删除
    }

    try {
      await invoke('delete_conversation', { id });
      await loadConversations();
      if (currentConversation?.id === id) {
        setCurrentConversation(null);
        setMessages([]);
      }
    } catch (error) {
      console.error('Failed to delete conversation:', error);
      alert('删除失败: ' + error);
    }
  };

  const updateConversationTitle = async (id: number, title: string) => {
    try {
      await invoke('update_conversation', { id, title });
      await loadConversations();
      if (currentConversation?.id === id) {
        setCurrentConversation({ ...currentConversation, title });
      }
      setEditingTitle(null);
    } catch (error) {
      console.error('Failed to update conversation:', error);
      alert('更新标题失败: ' + error);
    }
  };

  const handleModelChange = async (newModelId: number) => {
    if (!currentConversation) return;

    try {
      await invoke('update_conversation_model', {
        id: currentConversation.id,
        modelId: newModelId,
      });
      
      // Update local state
      setCurrentConversation({
        ...currentConversation,
        model_id: newModelId,
      });
      
      // Reload conversations to update the list
      await loadConversations();
    } catch (error) {
      console.error('Failed to update model:', error);
      alert('切换模型失败: ' + error);
    }
  };

  const sendMessage = async () => {
    if (!inputMessage.trim() || !currentConversation || isSending) return;

    const userMessage = inputMessage.trim();
    setInputMessage('');
    setIsSending(true);

    try {
      // Optimistically add user message to UI
      const tempUserMessage: Message = {
        id: Date.now(),
        conversation_id: currentConversation.id,
        role: 'user',
        content: userMessage,
        created_at: new Date().toISOString(),
      };
      setMessages(prev => [...prev, tempUserMessage]);

      // Send to AI and get response
      await invoke<string>('send_chat_message', {
        conversationId: currentConversation.id,
        message: userMessage,
      });

      // Reload messages to get server-saved versions
      await loadMessages(currentConversation.id);
      
      // Reload conversations to get updated title (if it was auto-generated)
      await loadConversations();
      
      // Update current conversation with new title if it was the first message
      if (messages.length === 1) { // Only user message was in the list
        const updatedConvs = await invoke<Conversation[]>('get_conversations');
        const updatedConv = updatedConvs.find(c => c.id === currentConversation.id);
        if (updatedConv && updatedConv.title !== currentConversation.title) {
          setCurrentConversation(updatedConv);
        }
      }
    } catch (error) {
      console.error('Failed to send message:', error);
      alert('发送失败: ' + error);
      // Remove optimistic user message on error
      setMessages(prev => prev.filter(m => m.id !== Date.now()));
    } finally {
      setIsSending(false);
    }
  };

  const handleKeyPress = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      sendMessage();
    }
  };

  if (!isAuthenticated) {
    return (
      <div className="flex flex-col items-center justify-center h-full">
        <MessageSquare className="w-16 h-16 text-muted-foreground mb-4" />
        <h2 className="text-xl font-semibold mb-2">需要认证</h2>
        <p className="text-muted-foreground">请先登录密码管理器</p>
      </div>
    );
  }

  return (
    <div className="flex h-full gap-4">
      {/* Sidebar - Conversations List */}
      <div className="w-80 flex flex-col bg-card border border-border rounded-lg">
        <div className="p-4 border-b border-border">
          <h2 className="text-lg font-semibold mb-3">对话列表</h2>
          
          {/* Model Selection */}
          {models.length > 0 ? (
            <div className="space-y-2">
              <p className="text-sm text-muted-foreground">选择模型开始新对话：</p>
              <div className="space-y-1">
                {models.map(model => (
                  <Button
                    key={model.id}
                    variant="outline"
                    size="sm"
                    onClick={() => createNewConversation(model.id)}
                    className="w-full justify-start gap-2"
                  >
                    <Plus className="w-4 h-4" />
                    {model.name}
                  </Button>
                ))}
              </div>
            </div>
          ) : (
            <p className="text-sm text-muted-foreground">
              请先在"AI模型管理"中添加模型
            </p>
          )}
        </div>

        <div className="flex-1 overflow-auto p-2">
          {conversations.length === 0 ? (
            <p className="text-sm text-muted-foreground text-center mt-4">
              暂无对话
            </p>
          ) : (
            <div className="space-y-1">
              {conversations.map(conv => (
                <div
                  key={conv.id}
                  className={`group relative p-3 rounded-md cursor-pointer transition-colors ${
                    currentConversation?.id === conv.id
                      ? 'bg-primary/10 border border-primary'
                      : 'hover:bg-muted border border-transparent'
                  }`}
                  onClick={() => setCurrentConversation(conv)}
                >
                  {editingTitle === conv.id ? (
                    <div className="flex gap-1" onClick={(e) => e.stopPropagation()}>
                      <Input
                        value={editTitle}
                        onChange={(e) => setEditTitle(e.target.value)}
                        onKeyPress={(e) => {
                          if (e.key === 'Enter') {
                            updateConversationTitle(conv.id, editTitle);
                          }
                        }}
                        className="h-7 text-sm"
                        autoFocus
                      />
                      <Button
                        size="sm"
                        variant="ghost"
                        onClick={() => updateConversationTitle(conv.id, editTitle)}
                      >
                        <Check className="w-3 h-3" />
                      </Button>
                      <Button
                        size="sm"
                        variant="ghost"
                        onClick={() => setEditingTitle(null)}
                      >
                        <X className="w-3 h-3" />
                      </Button>
                    </div>
                  ) : (
                    <>
                      <div className="flex items-start justify-between gap-2">
                        <div className="flex-1 min-w-0">
                          <p className="text-sm font-medium truncate">{conv.title}</p>
                          <p className="text-xs text-muted-foreground">
                            {new Date(conv.updated_at).toLocaleString('zh-CN')}
                          </p>
                        </div>
                        <div className="flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
                          <Button
                            size="sm"
                            variant="ghost"
                            onClick={(e) => {
                              e.stopPropagation();
                              setEditingTitle(conv.id);
                              setEditTitle(conv.title);
                            }}
                          >
                            <Edit2 className="w-3 h-3" />
                          </Button>
                          <Button
                            size="sm"
                            variant="ghost"
                            onClick={(e) => deleteConversation(conv.id, e)}
                            className="text-destructive hover:text-destructive"
                            title="删除对话"
                          >
                            <Trash2 className="w-3 h-3" />
                          </Button>
                        </div>
                      </div>
                    </>
                  )}
                </div>
              ))}
            </div>
          )}
        </div>
      </div>

      {/* Main Chat Area */}
      <div className="flex-1 flex flex-col bg-card border border-border rounded-lg">
        {currentConversation ? (
          <>
            {/* Chat Header */}
            <div className="p-4 border-b border-border">
              <div className="flex items-center justify-between">
                <div className="flex-1">
                  <h2 className="text-lg font-semibold">{currentConversation.title}</h2>
                  <p className="text-xs text-muted-foreground mt-1">
                    {models.find(m => m.id === currentConversation.model_id)?.model_type || ''}
                  </p>
                </div>
                <div className="flex items-center gap-4">
                  {/* Auto-speak toggle */}
                  {ttsSupported && (
                    <div className="flex items-center gap-2">
                      <label className="text-sm text-muted-foreground cursor-pointer" htmlFor="auto-speak">
                        自动朗读
                      </label>
                      <button
                        id="auto-speak"
                        type="button"
                        onClick={() => setAutoSpeak(!autoSpeak)}
                        className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${
                          autoSpeak ? 'bg-primary' : 'bg-muted'
                        }`}
                        title={autoSpeak ? '关闭自动朗读' : '开启自动朗读'}
                      >
                        <span
                          className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
                            autoSpeak ? 'translate-x-6' : 'translate-x-1'
                          }`}
                        />
                      </button>
                    </div>
                  )}
                  
                  {/* Model selector */}
                  <div className="flex items-center gap-2">
                    <label className="text-sm text-muted-foreground">模型:</label>
                    <select
                      value={currentConversation.model_id}
                      onChange={(e) => handleModelChange(parseInt(e.target.value))}
                      className="px-3 py-1 border border-input rounded-md bg-background text-sm min-w-[150px]"
                    >
                      {models.map(model => (
                        <option key={model.id} value={model.id}>
                          {model.name}
                        </option>
                      ))}
                    </select>
                  </div>
                </div>
              </div>
            </div>

            {/* Messages */}
            <div className="flex-1 overflow-auto p-4 space-y-4">
              {isLoading ? (
                <div className="flex justify-center items-center h-full">
                  <Loader2 className="w-8 h-8 animate-spin text-muted-foreground" />
                </div>
              ) : messages.length === 0 ? (
                <div className="flex flex-col items-center justify-center h-full text-muted-foreground">
                  <MessageSquare className="w-16 h-16 mb-4" />
                  <p>开始对话吧</p>
                </div>
              ) : (
                <>
                  {messages.map((msg, index) => (
                    <motion.div
                      key={msg.id}
                      initial={{ opacity: 0, y: 20 }}
                      animate={{ opacity: 1, y: 0 }}
                      transition={{ delay: index * 0.05 }}
                      className={`flex ${msg.role === 'user' ? 'justify-end' : 'justify-start'}`}
                    >
                      <div className="flex items-start gap-2 max-w-[80%]">
                        <div
                          className={`flex-1 p-3 rounded-lg ${
                            msg.role === 'user'
                              ? 'bg-primary text-primary-foreground'
                              : 'bg-muted'
                          }`}
                        >
                          <p className="text-sm whitespace-pre-wrap">{msg.content}</p>
                          <p className="text-xs mt-1 opacity-70">
                            {new Date(msg.created_at).toLocaleTimeString('zh-CN')}
                          </p>
                        </div>
                        {msg.role === 'assistant' && ttsSupported && (
                          <Button
                            size="sm"
                            variant="ghost"
                            onClick={() => speakMessage(msg.id!, msg.content)}
                            className={`flex-shrink-0 ${speakingMessageId === msg.id ? 'text-primary' : ''}`}
                            title={speakingMessageId === msg.id ? '停止朗读' : '朗读消息'}
                          >
                            {speakingMessageId === msg.id ? (
                              <VolumeX className="w-4 h-4" />
                            ) : (
                              <Volume2 className="w-4 h-4" />
                            )}
                          </Button>
                        )}
                      </div>
                    </motion.div>
                  ))}
                  {isSending && (
                    <div className="flex justify-start">
                      <div className="bg-muted p-3 rounded-lg">
                        <Loader2 className="w-5 h-5 animate-spin" />
                      </div>
                    </div>
                  )}
                  <div ref={messagesEndRef} />
                </>
              )}
            </div>

            {/* Input Area */}
            <div className="p-4 border-t border-border">
              <div className="flex gap-2">
                <Input
                  value={inputMessage}
                  onChange={(e) => setInputMessage(e.target.value)}
                  onKeyPress={handleKeyPress}
                  placeholder={isListening ? "🎤 正在聆听..." : "输入消息... (Enter发送, Shift+Enter换行)"}
                  disabled={isSending}
                  className="flex-1"
                />
                {voiceSupported && (
                  <Button
                    onClick={toggleVoiceInput}
                    variant={isListening ? "default" : "outline"}
                    className={isListening ? "bg-red-500 hover:bg-red-600" : ""}
                    title={isListening ? "停止语音输入" : "开始语音输入"}
                    type="button"
                  >
                    {isListening ? <MicOff className="w-4 h-4" /> : <Mic className="w-4 h-4" />}
                  </Button>
                )}
                <Button
                  onClick={sendMessage}
                  disabled={!inputMessage.trim() || isSending}
                  className="gap-2"
                >
                  {isSending ? (
                    <Loader2 className="w-4 h-4 animate-spin" />
                  ) : (
                    <Send className="w-4 h-4" />
                  )}
                  发送
                </Button>
              </div>
              {isListening && (
                <div className="mt-2 flex items-center gap-2 text-sm text-muted-foreground">
                  <div className="w-2 h-2 bg-red-500 rounded-full animate-pulse" />
                  正在聆听...请说话
                </div>
              )}
            </div>
          </>
        ) : (
          <div className="flex flex-col items-center justify-center h-full text-muted-foreground">
            <MessageSquare className="w-16 h-16 mb-4" />
            <p>选择一个对话或创建新对话</p>
          </div>
        )}
      </div>
    </div>
  );
}
